#include <algorithm/analytical_model/io/json/converter/shared/data/world/sun/sun_position/SunPosition.h>

using namespace solar;

void solar::tag_invoke(const boost::json::value_from_tag& /*unused*/,
                       boost::json::value& json_value, const SunPosition& sun_position)
{
    auto azimuth = SOLAR_GET_VALUE(SunPosition, azimuth_, sun_position);
    auto elevation = SOLAR_GET_VALUE(SunPosition, elevation_, sun_position);
    auto dni = SOLAR_GET_VALUE(SunPosition, dni_, sun_position);
    auto trackable = SOLAR_GET_VALUE(SunPosition, trackable_, sun_position);
    json_value = {
        {  "azimuth",   azimuth},
        {"elevation", elevation},
        {      "dni",       dni},
        {"trackable", trackable}
    };
}

auto solar::tag_invoke(const boost::json::value_to_tag<SunPosition>& /*unused*/,
                       const boost::json::value& json_value) -> SunPosition
{
    const auto* value_ptr = json_value.if_object();
    if (value_ptr == nullptr)
    {
        return {};
    }
    SunPosition result;
    if (const auto* azimuth_value = value_ptr->if_contains("azimuth");
        azimuth_value != nullptr)
    {
        SOLAR_SET_VALUE(SunPosition, azimuth_, azimuth_value->to_number<double>(), result)
    }
    if (const auto* elevation_value = value_ptr->if_contains("elevation");
        elevation_value != nullptr)
    {
        SOLAR_SET_VALUE(SunPosition, elevation_, elevation_value->to_number<double>(), result)
    }
    if (const auto* dni_value = value_ptr->if_contains("dni");
        dni_value != nullptr)
    {
        SOLAR_SET_VALUE(SunPosition, dni_, dni_value->to_number<double>(), result)
    }
    if (const auto* trackable_value = value_ptr->if_contains("trackable");
        trackable_value != nullptr)
    {
        SOLAR_SET_VALUE(SunPosition, trackable_, trackable_value->get_bool(), result)
    }
    return result;
}
